﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ControlAccessUser.Presenter;
using ControlAccessUser.Model;

namespace ControlAccessUser.Tests
{
    [TestClass]
    public class SearchUserTest
    {
        MockSearchUserView vSearchUser;
        PresenterSearchUser pSearchUser;

        [TestInitialize]
        public void Initial()
        {
            vSearchUser = new MockSearchUserView();
            pSearchUser = new PresenterSearchUser(vSearchUser);
            ControlAccessUser.DataAccess.ControlAccessUserEntities.Instance.Users.Add(new User() { UserFirstName = "Gary", UserLastName = "Rioja", UserName = "gary", UserPassword = "123456" });
            ControlAccessUser.DataAccess.ControlAccessUserEntities.Instance.Users.Add(new User() { UserFirstName = "Gaston", UserLastName = "Torrez", UserName = "gaston", UserPassword = "123456" });
            ControlAccessUser.DataAccess.ControlAccessUserEntities.Instance.SaveChanges();
        }

        [TestCleanup]
        public void Clean()
        {
            ControlAccessUser.DataAccess.ControlAccessUserEntities.Instance.LimpiarDB();
        }

        /// <summary>
        /// Realiza una busqueda tomando como criterio el nombre de usuario.
        /// </summary>
        [TestMethod]
        public void SearchUserByFirstName()
        {
            vSearchUser.SetFieldFirstName();
            pSearchUser.SearchUserByRelativeFields();
            Assert.AreNotEqual(null, vSearchUser.UsersFound);
            Assert.AreEqual(true, vSearchUser.UsersFound.Count>0);
        }

        /// <summary>
        /// Realiza una busqueda tomando como criterio el apellido de usuario.
        /// </summary>
        [TestMethod]
        public void SearchUserByLastName()
        {
            vSearchUser.SetFieldLastName();
            pSearchUser.SearchUserByRelativeFields();
            Assert.AreNotEqual(null, vSearchUser.UsersFound);
            Assert.AreEqual(1, vSearchUser.UsersFound.Count);
        }

        /// <summary>
        /// Realiza una busqueda tomando como criterio el UserName.
        /// </summary>
        [TestMethod]
        public void SearchUserByUserName()
        {
            vSearchUser.SetFieldUserName();
            pSearchUser.SearchUserByRelativeFields();
            Assert.AreNotEqual(null, vSearchUser.UsersFound);
            Assert.AreEqual(2, vSearchUser.UsersFound.Count);
        }

        private int GetLastUserId()
        {
            return (from user in ControlAccessUser.DataAccess.ControlAccessUserEntities.Instance.Users
                    select user.UserId).Max();
        }

        [TestMethod]
        public void SearchUserByUserId()
        {
            int UserId = GetLastUserId();
            vSearchUser.SetFieldUserId(UserId);
            pSearchUser.SearchUserByRelativeFields();
            Assert.AreNotEqual(null, vSearchUser.UsersFound);
            Assert.AreEqual(1, vSearchUser.UsersFound.Count);
        }

        [TestMethod]
        public void SearchUser()
        {
            vSearchUser.SetFieldFirstNameAndLastName();
            pSearchUser.SearchUserByRelativeFields();
            Assert.AreNotEqual(null, vSearchUser.UsersFound);
            Assert.AreEqual(1, vSearchUser.UsersFound.Count);
        }

        private User SearchUserByUserName(string UserName)
        {
            return (from user in ControlAccessUser.DataAccess.ControlAccessUserEntities.Instance.Users
                    where
                    user.UserName == UserName                    
                    select user).ToList().First();
        }
        private ICollection<Login> SearchLoginsByUser(User User)
        {
            return (from login in ControlAccessUser.DataAccess.ControlAccessUserEntities.Instance.Logins
                    where login.UserId == User.UserId
                    select login).ToList();
        }

        [TestMethod]
        public void LogoutUserByManager()
        {
            User User = SearchUserByUserName("gaston");
            User Manager = SearchUserByUserName("gary");
            Login login = new Login() {DataTimeLoginUser=DateTime.Now, DataTimeLogoutUser=null, UserId=User.UserId };
            DataAccess.ControlAccessUserEntities.Instance.Logins.Add(login);
            DataAccess.ControlAccessUserEntities.Instance.SaveChanges();
            vSearchUser.SetSelectedUserToLogoutByManager(User, Manager);
            pSearchUser.LogoutSelectedUser();
            ICollection<Login> Logins = SearchLoginsByUser(User);

            Assert.AreNotEqual(null, Logins.First().DataTimeLogoutUser);
            Assert.AreEqual(1,Logins.Count());
        }    

        [TestMethod]
        public void LogoutUserByManagerCancel()
        {
            User User = SearchUserByUserName("gaston");
            User Manager = SearchUserByUserName("gary");
            Login Login = new Login() { DataTimeLoginUser = DateTime.Now, DataTimeLogoutUser = null, UserId = User.UserId };
            DataAccess.ControlAccessUserEntities.Instance.Logins.Add(Login);
            DataAccess.ControlAccessUserEntities.Instance.SaveChanges();
            vSearchUser.SetSelectedUserToLogoutByManagerCancel(User, Manager);
            pSearchUser.LogoutSelectedUser();
            ICollection<Login> Logins = SearchLoginsByUser(User);

            Assert.AreEqual(null, Logins.First().DataTimeLogoutUser);
            Assert.AreEqual(1, Logins.Count());
            Assert.AreEqual(null,vSearchUser.ErrorMessage);
        }

        [TestMethod]
        public void LogoutUserByManagerError()
        {
            User User = SearchUserByUserName("gary");
            User Manager = SearchUserByUserName("gary");
            Login Login = new Login() { DataTimeLoginUser = DateTime.Now, DataTimeLogoutUser = null, UserId = User.UserId };
            DataAccess.ControlAccessUserEntities.Instance.Logins.Add(Login);
            DataAccess.ControlAccessUserEntities.Instance.SaveChanges();
            vSearchUser.SetSelectedUserToLogoutByManager(User, Manager);
            pSearchUser.LogoutSelectedUser();
            ICollection<Login> Logins = SearchLoginsByUser(User);

            Assert.AreEqual(null, Logins.First().DataTimeLogoutUser);
            Assert.AreEqual(1, Logins.Count());
            Assert.AreNotEqual(null, vSearchUser.ErrorMessage);
        }
    }
}
